Shiny.addCustomMessageHandler("choropleth_values", function(message) {

    var dataset = message;

    //var width = 800;
    //var height = 600;

    var projection = d3.geoEquirectangular()
	.translate([0, 0]);

    var path = d3.geoPath()
	.projection(projection);

    var x = d3.scaleLinear()
	.domain(dataset.percent)
	.rangeRound([600, 860]);

    var dataDomain = [];

    function getDomain (l){
	/*for (var i = 0; i < l.length; i++){
	    dataDomain[i] = l[i * 3];
	}
	return dataDomain.sort(function(a, b){return (a - b);});*/



	var v = d3.max(l) / 9;
	return [v, v*2, v*3, v*4, v*5, v*6, v*7, v*8];
    }


    var color = d3.scaleThreshold()
	.domain(getDomain(dataset.percent)).range(d3.schemeBlues[9]);
	/*.range(['#fff7f3','#fde0dd','#fcc5c0','#fa9fb5',
		'#f768a1','#dd3497','#ae017e','#7a0177',
		'#49006a','#ffffff','#f0f0f0','#d9d9d9',
		'#bdbdbd','#969696','#737373','#525252',
		'#252525','#000000']);*/


    var choropleth =  d3.select("#choropleth_area")
	.append("svg")
	.attr("width", width)
	.attr("height", height);

    var g = choropleth.append("g")
	.attr("class", "key")
	.attr("transform", "translate(0,40)");

    g.selectAll("rect")
	.data(color.range().map(function(d) {
	    d = color.invertExtent(d);
	    if (d[0] == null) d[0] = x.domain()[0];
	    if (d[1] == null) d[1] = x.domain()[1];
	    return d;
	}))
	.enter().append("rect")
	.attr("height", 8)
	.attr("x", function(d) { return x(d[0]); })
	.attr("width", function(d) { return x(d[1]) - x(d[0]); })
	.attr("fill", function(d) { return color(d[0]); });

    g.append("text")
	.attr("class", "caption")
	.attr("x", x.range()[0])
	.attr("y", -6)
	.attr("fill", "#000")
	.attr("text-anchor", "start")
	.attr("font-weight", "bold")
	.text("Acidentes");

    /*g.call(d3.axisBottom(x)
	   .tickSize(13)
	   .tickFormat(function(x) { return x; })
	   .tickValues(color.domain()))
	.select(".domain")
	.remove();*/

    var zooming = function() {
	var offset = [d3.event.transform.x, d3.event.transform.y];

	var newScale = d3.event.transform.k * 2000;

	projection.translate(offset)
	    .scale(newScale);

	choropleth.selectAll("path")
	    .style("stroke", "black")
	    .style("stroke-width", 1)
	    .attr("d", path);
    };

    var zoom = d3.zoom()
	.on("zoom", zooming);

    var center = projection([-12.1, -50.6]);

    var map = choropleth.append("g")
	.attr("id", "map")
	.call(zoom)
	.call(zoom.transform, d3.zoomIdentity
	      .translate(width, height/2)
	      .scale(0.25)
	      .translate(-center[0], -center[1]));

    //invisible rect covering all svg, so we can drag anywhere
    map.append("rect")
	.attr("x", 0)
	.attr("y", 0)
	.attr("width", width)
	.attr("height", height)
	.attr("opacity", 0);

    d3.json("uf.json").then(function(json) {

	for (var i = 0; i < dataset.uf.length; i++) {
	    var dataState = dataset.uf[i];
	    var dataValue = parseFloat(dataset.percent[i]);

	    for (var j = 0; j < json.features.length; j++) {
		var jsonState = json.features[j].properties.NOME_UF;

		if (dataState == jsonState) {
		    json.features[j].properties.value = dataValue;
		    break;
		}
	    }
	}

	map.selectAll("path")
	    .data(json.features)
	    .enter()
	    .append("path")
	    .attr("d", path)
	    .style("stroke", "black")
	    .style("stroke-width", 1)
	    .style("fill",function(d) {
		var value = d.properties.value;

		if (value) {
		    return color(value);
		    //return "rgb(0, 0, " + Math.round(Math.log2(value) * 11) + ")";
		} else {
		    return "#ccc";
		}
	    });

	EnablePan();
    });

    var EnablePan = function() {

	// TODO fix this ugly hack, we shouldn't need to select the body
	d3.select("body").on("keydown", function() {
	    var moveAmount = 50;
	    var key = d3.event.key;
	    var x = 0;
	    var y = 0;

	    switch(key) {
	    case "ArrowUp":
		y += moveAmount;
		break;
	    case "ArrowDown":
		y -= moveAmount;
		break;
	    case "ArrowLeft":
		x += moveAmount;
		break;
	    case "ArrowRight":
		x -= moveAmount;
		break;
	    default:
		break;
	    }

	    map.transition()
		.call(zoom.translateBy, x, y);

	});
    };
});
